<script setup lang="ts">
import {
  onActivated,
  ref,
  computed,
  watch,
  Ref,
  shallowRef,
  nextTick,
  onMounted,
  onUnmounted,
  onErrorCaptured,
  onDeactivated,
  reactive
} from 'vue'
import {
  IconCalendarClock,
  IconCalendar,
  IconPlus,
  IconSearch,
  IconFile,
  IconDownload,
  IconDelete,
  IconCheck,
  IconEdit,
  IconClose,
  IconImage,
  IconMusic,
  IconFile as IconVideo,
  IconFile as IconFileWord,
  IconFile as IconFileExcel,
  IconFile as IconFilePdf,
  IconFile as IconFileZip,
  IconCode,
  IconFile as IconFileText,
  IconInfoCircle,
  IconEye
} from '@arco-design/web-vue/es/icon'
import { Message, Modal, Notification } from '@arco-design/web-vue'
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc' // 导入 UTC 插件
import {
  addMembersUsingPost,
  getMembersUsingGet,
  updateProjectUsingPost,
  updateUserInProjectUsingPost,
  pageProjectDynamicUsingPost,
  removeMembersUsingPost,
  getTaskCountByProIdUsingGet,
  getProjectUsingGet
} from '@/api/projectController'
import { useTeamStore } from '@/store/index'
import { useUserStore } from '@/store'
import { pageUserInTeamUsingPost } from '@/api/teamController'
import { ProjectStatus, PROJECT_STATUS_CONFIG, getProjectStatusList } from '@/constants/projectType'
import '@wangeditor/editor/dist/css/style.css' // 引入编辑器样式
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { IEditorConfig, IDomEditor } from '@wangeditor/editor'
import { formatFileSize, downloadFile, getFileIcon, getFileType } from '@/utils/file'

import {
  addAttacheUsingPost,
  deleteAttacheUsingDelete,
  pageAttachesUsingPost
} from '@/api/attacheController'
// 添加组件导入
import FilePreview from '@/components/attaches/FilePreview.vue'
import { useFilePreview } from '@/composables/useFilePreview'
import { addMilestoneUsingPost } from '@/api/milStoneController'
import { addIterationUsingPost } from '@/api/iterationController'
import { uploadFileUsingPost } from '@/api/fileController'
import MilestoneTasksList from '@/components/projects/MilestoneTasksList.vue'
// 附件预览 （composiables 代码复用）
const { previewVisible, previewFile, handlePreview, closePreview } = useFilePreview()
// 配置 dayjs 使用 UTC 插件
dayjs.extend(utc)

defineOptions({
  name: 'ProjectOverview'
})
const emit = defineEmits<{}>()
const props = defineProps<{
  proId: number
}>()

const userStore = useUserStore()
const teamStore = useTeamStore()
//#region 项目数据定义
const currentProject = ref<API.ProjectVo | null>(null)
//#endregion
// 获取项目任务统计数
const taskCount = ref<API.TaskCountVo>()
const getProjectTaskCount = async () => {
  const res: any = await getTaskCountByProIdUsingGet({ proId: Number(props.proId) })
  if (res.code === 0) {
    taskCount.value = res.data
  } else {
    Message.error(res.msg || '获取项目任务统计数失败')
  }
}
//项目更新参数
const updateProjectRequest: Ref<API.UpdateProjectRequest> = ref<API.UpdateProjectRequest>({
  id: currentProject.value?.id,
  ownerId: currentProject.value?.ownerId,
  title: currentProject.value?.title,
  startTime: currentProject.value?.startTime,
  endTime: currentProject.value?.endTime,
  status: currentProject.value?.status,
  description: currentProject.value?.description,
  remark: currentProject.value?.remark
})
//#endregion

//#region 成员列表
// 获取项目成员列表
const projectMemberList = ref<API.UserInProjectVo[]>([])
const getProjectMemberList = async () => {
  if (!currentProject.value?.id) return

  try {
    const res: any = await getMembersUsingGet({
      id: currentProject.value.id
    })
    if (res.code === 0) {
      projectMemberList.value = res.data
      console.log(projectMemberList.value)
    }
  } catch (error) {
    Message.error('获取项目成员失败')
  }
}
//获取我自己
const userInProject: any = computed(() => {
  if (!userStore.user?.id || !projectMemberList.value.length) return null
  return projectMemberList.value.find((item) => item.userId === userStore.user?.id)
})

//获取团队成员列表
// 请求参数
const userInTeamRequest: Ref<API.UserInTeamRequest> = ref({
  current: 1,
  pageSize: 1000,
  teamId: teamStore.selectedTeam?.id,
  name: '',
  email: '',
  phone: '',
  role: -1
})
const teamUserVoList = ref<API.UserInTeamVo[]>([])
const loadTeamUserList = async () => {
  if (!teamStore.selectedTeam?.id) return
  const res: any = await pageUserInTeamUsingPost(userInTeamRequest.value)
  teamUserVoList.value = res.data.records
}
// 添加成员选择相关的状态
const memberSelectVisible = ref(false)
const selectedUsers = ref<number[]>([])

// 修改处理添加成员的函数
const handleAddMember = async () => {
  memberSelectVisible.value = true
  selectedUsers.value = [] // 重置选择
  await loadTeamUserList()
  await initData()
}

// 处理成员选择
const handleMemberSelect = (userId: number, checked: boolean) => {
  if (checked) {
    selectedUsers.value.push(userId)
  } else {
    selectedUsers.value = selectedUsers.value.filter((id) => id !== userId)
  }
}

// 处理确认添加成员
const handleConfirmAddMembers = async () => {
  if (selectedUsers.value.length === 0) {
    Message.warning('请选择要添加的成员')
    return
  }

  try {
    const res: any = await addMembersUsingPost({
      userIdList: selectedUsers.value,
      proId: currentProject.value?.id
    })
    if (res.code === 0) {
      Message.success('添加成员成功')
    } else {
      Message.error(res.message || '添加成员失败')
    }
  } catch (error) {
    Message.error('添加成员失败')
  } finally {
    memberSelectVisible.value = false
    await getProjectMemberList() // 刷新成员列表
  }
}

// 判断用户是否已经是项目成员
const isProjectMember = (userId: number) => {
  return projectMemberList.value.some((member) => member.userId === userId)
}

// 搜索相关
const searchKeyword = ref('')

const handleSearchMember = (value: string) => {
  console.log('搜索成员:', value)
  // TODO: 实现搜索逻辑
}

// 处理编辑成员
const handleEditMember = (member: any) => {
  Message.info(`编辑成员: ${member.name}`)
}

// 处理移除成员
const handleRemoveMember = (member: any) => {
  Modal.confirm({
    title: '移除成员',
    content: `确定要移除成员 ${member.username || member.name} 吗？`,
    okText: '确定移除',
    cancelText: '取消',
    okButtonProps: {
      status: 'danger'
    },
    onOk: async () => {
      try {
        const res: any = await removeMembersUsingPost({
          proId: Number(currentProject.value?.id),
          userIdList: [member.userId]
        })

        if (res.code === 0) {
          Message.success('成员移除成功')
        } else {
          Message.error(res.message || '移除失败')
        }
      } catch (error) {
        Message.error('移除成员失败')
      } finally {
        await initData()
      }
    }
  })
}
//#endregion

// 编辑器配置
const editorConfig: Partial<IEditorConfig> = {
  placeholder: '请输入内容...',
  scroll: true,
  autoFocus: false,
  MENU_CONF: {
    uploadImage: {
      // 修改自定义上传函数
      customUpload: async (file: File, insertFn: any) => {
        try {
          const uploadRes: any = await uploadFileUsingPost(file)

          if (uploadRes.code === 0 && uploadRes.data) {
            // 上传成功，插入图片
            insertFn(uploadRes.data)
          } else {
            Message.error(uploadRes.message || '图片上传失败')
          }
        } catch (error) {
          console.error('图片上传失败:', error)
          Message.error('图片上传失败')
        }
      },
      // 上传之前触发
      onBeforeUpload: (file: File) => {
        // 验证文件大小
        if (file.size > 10 * 1024 * 1024) {
          Message.error('图片大小不能超过 10M')
          return false
        }

        // 验证文件类型
        const fileType = file.type || ''
        const isImage =
          fileType.startsWith('image/') || /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(file.name)

        if (!isImage) {
          Message.error('只能上传图片文件')
          return false
        }

        return true
      }
    }
  }
}

//#region 文件列表
// 文件列表数据
const allAttaches = ref<API.AttachesVo[]>([])
const fileLoading = ref(false)

// 附件上传请求参数
const addAttacheRequest = ref<API.addAttacheUsingPOSTParams>({
  type: 1, // 项目类型
  typeId: currentProject.value?.id as number, // 项目ID
  fileName: ''
})

// 处理文件上传前的验证
const beforeUpload = (file: File) => {
  const maxSize = 10 * 1024 * 1024 // 10MB

  if (file.size > maxSize) {
    Message.error('文件大小不能超过10MB')
    return false
  }

  // 设置文件名
  addAttacheRequest.value.fileName = file.name
  return true
}

// 处理文件上传
const handleUpload = async (option: any) => {
  const { fileItem } = option

  try {
    // 构建上传参数
    addAttacheRequest.value.fileName = fileItem.file.name
    addAttacheRequest.value.typeId = currentProject.value?.id as number
    // 上传文件
    const res: any = await addAttacheUsingPost(addAttacheRequest.value, fileItem.file)

    if (res.code === 0) {
      Message.success('上传成功')
      // 刷新文件列表
      pageAttacheRequest.value.current = 1
      await loadMoreAttaches()
    } else {
      Message.error(res.message || '上传失败')
    }
  } catch (error) {
    Message.error('文件上传失败 ' + error)
  }
}

// 加载文件列表
const pageAttacheRequest = ref<API.PageAttacheRequest>({
  current: 1,
  pageSize: 10,
  typeId: currentProject.value?.id as number,
  type: 1
})

// 添加是否有更多文件的计算属性
const hasMoreAttaches = ref(true)

// 加载更多文件
const loadMoreAttaches = async () => {
  if (fileLoading.value) return

  fileLoading.value = true
  try {
    pageAttacheRequest.value.typeId = currentProject.value?.id
    const res: any = await pageAttachesUsingPost(pageAttacheRequest.value)
    if (res.code === 0) {
      // 如果是第一页，直接赋值
      if (pageAttacheRequest.value.current === 1) {
        allAttaches.value = res.data.records
      } else {
        // 否则追加数据
        allAttaches.value = [...allAttaches.value, ...res.data.records]
      }
      // 判断是否还有更多数据
      hasMoreAttaches.value = allAttaches.value.length < res.data.total
      // 更新页码
      if (hasMoreAttaches.value) {
        pageAttacheRequest.value.current += 1
      }
    } else {
      Message.error(res.message || '获取文件列表失败')
    }
  } finally {
    fileLoading.value = false
  }
}

// 处理文件删除
const deleteAttacheRequest: Ref<API.DeleteAttacheRequest> = ref({
  type: 1,
  typeId: currentProject.value?.id as number,
  attacheId: undefined
})

const handleDeleteAttache = async (attache: any) => {
  // 添加确认框
  Modal.confirm({
    title: '确认删除',
    content: `确定要删除附件 "${attache.name}" 吗？`,
    okText: '确认删除',
    cancelText: '取消',
    onOk: async () => {
      try {
        deleteAttacheRequest.value.typeId = currentProject.value?.id
        deleteAttacheRequest.value.attacheId = attache.id
        const res: any = await deleteAttacheUsingDelete(deleteAttacheRequest.value)
        if (res.code === 0) {
          Notification.success('删除成功')
          allAttaches.value = allAttaches.value.filter(
            (attacheVo: any) => attacheVo.id !== attache.id
          )
        } else {
          Notification.error(res.message || '删除失败')
        }
      } catch (e) {
        Notification.error('删除失败 ' + e)
      }
    }
  })
}
//#endregion

//#region 项目状态
// 修改项目状态的初始化
const projectStatus = ref(currentProject.value?.status || ProjectStatus.PLANNING)

// 监听 currentProject 的变化来更新状态
watch(
  () => currentProject.value?.status,
  (newStatus) => {
    if (newStatus !== undefined) {
      projectStatus.value = newStatus
    }
  },
  { immediate: true }
)

// 添加获取状态文字的计算属性
const statusText = computed(() => {
  return PROJECT_STATUS_CONFIG[projectStatus.value]?.label || '未知'
})

// 修改状态列表的计算属性，排除"已逾期"状态
const statusList = computed(() => {
  return Object.values(PROJECT_STATUS_CONFIG)
    .filter((status) => status.value !== ProjectStatus.OVERDUE) // 过滤掉已逾期状态
    .map((status) => ({
      value: status.value,
      label: status.label,
      color: status.color
    }))
})

// 添加状态显示值的计算属性
const projectStatusDisplay = computed({
  get: () => {
    // 根据当前状态值返回对应的状态对象
    return PROJECT_STATUS_CONFIG[projectStatus.value]?.value || ProjectStatus.NOT_STARTED
  },
  set: (value) => {
    projectStatus.value = value
  }
})

// 修改状态选择器的禁用逻辑
const isStatusSelectDisabled = computed(() => {
  // 如果当前状态是已逾期
  if (currentProject.value?.status === ProjectStatus.OVERDUE) {
    if (!currentProject.value?.endTime) return true
    const now = new Date()
    const endDate = new Date(currentProject.value.endTime)
    // 如果当前时间大于截止时间，且进度不为100%，则禁用选择器
    return now > endDate && currentProject.value.progress !== 1
  }
  return false
})

// 添加重置函数
const resetUpdateProjectRequest = (field?: keyof API.UpdateProjectRequest) => {
  if (field) {
    // 重置指定字段
    updateProjectRequest.value[field] = undefined
  } else {
    // 重置所有字段为初始状态
    updateProjectRequest.value = {
      id: currentProject.value?.id,
      ownerId: undefined,
      title: undefined,
      startTime: undefined,
      endTime: undefined,
      status: undefined,
      description: undefined,
      remark: undefined
    }
  }
}

// 修改状态变更处理函数
const handleStatusChange = async (value: ProjectStatus) => {
  try {
    updateProjectRequest.value.id = Number(currentProject.value?.id)
    updateProjectRequest.value.status = value
    const res: any = await updateProjectUsingPost(updateProjectRequest.value)
    if (res.code === 0) {
      Message.success('状态更新成功')
    } else {
      Message.error(res.message || '状态更新失败')
    }
  } catch (error) {
    Message.error('状态更新失败')
  } finally {
    resetUpdateProjectRequest('status')
  }
}

// 添加当前状态显示文本的计算属性
const currentStatusText = computed(() => {
  return PROJECT_STATUS_CONFIG[projectStatus.value]?.label || '未知'
})

// 添加是否显示选择器的计算属性
const showStatusSelect = computed(() => {
  return projectStatus.value !== ProjectStatus.OVERDUE
})
//#endregion

//#region 项目动态
// 添加动态列表相关的状态
const dynamicList = ref<API.ProjectDynamicVo[]>([])
const dynamicLoading = ref(false)
const hasMoreDynamic = ref(true)

// 分页请求参数
const pageProjectDynamicRequest = ref<API.ProjectDynamicRequest>({
  current: 1,
  pageSize: 10,
  proId: currentProject.value?.id
})

// 获取动态列表
const getDynamicList = async (isLoadMore = false) => {
  if (dynamicLoading.value || (!isLoadMore && !currentProject.value?.id)) return

  try {
    dynamicLoading.value = true
    pageProjectDynamicRequest.value.proId = currentProject.value?.id
    const res: any = await pageProjectDynamicUsingPost(pageProjectDynamicRequest.value)

    if (res.code === 0) {
      if (isLoadMore) {
        // 加载更多时追加数据
        dynamicList.value.push(...res.data.records)
      } else {
        // 首次加载或刷新时替换数据
        dynamicList.value = res.data.records
      }

      // 判断是否还有更多数据
      hasMoreDynamic.value = dynamicList.value.length < res.data.total
      // 更新页码
      if (hasMoreDynamic.value) {
        pageProjectDynamicRequest.value.current++
      }
    }
  } catch (error) {
    Message.error('获取项目动态失败')
  } finally {
    dynamicLoading.value = false
  }
}

// 处理加载更多
const handleLoadMoreDynamic = async () => {
  await getDynamicList(true)
}

// 监听项目ID变化，重新加载动态
watch(
  () => currentProject.value?.id,
  async (newId) => {
    if (newId) {
      // 重置分页参数
      pageProjectDynamicRequest.value = {
        current: 1,
        pageSize: 10,
        proId: newId
      }
      // 重新加载数据
      await getDynamicList()
    }
  },
  { immediate: true }
)

const ownerPopupVisible = ref(false)

// 修改处理负责人选择的函数
const handleOwnerSelect = async (member: any) => {
  // 如果点击的是当前负责人，直接关闭弹窗
  if (member.userIid === currentProject.value?.owner?.id) {
    Message.info(`当前已是负责人：${member.name}（ID: ${member.userId}）`)
    ownerPopupVisible.value = false
    return
  }
  updateProjectRequest.value.id = Number(currentProject.value?.id)
  updateProjectRequest.value.ownerId = member.userId
  try {
    const res: any = await updateProjectUsingPost(updateProjectRequest.value)
    if (res.code === 0) {
    } else {
      Message.error(res.message || '更新失败')
    }
  } catch (error) {
    Message.error('更新失败')
  } finally {
    resetUpdateProjectRequest('ownerId') // 重置 ownerId 字段
    ownerPopupVisible.value = false

    await initData()
  }
}

// 添加开始时间的显示状态控制
const startTimeVisible = ref(false)

// 添加截止时间的显示状态控制
const endTimeVisible = ref(false)

// 修改时间变更处理函数
const handleTimeChange = async (type: 'start' | 'end', value: string) => {
  // 非管理员不可修改
  if (userInProject.value?.role !== 1) {
    return
  }
  //开始时间不能大于截止时间且截至时间不能早于开始时间
  if (type === 'start' && dayjs(value).isAfter(dayjs(currentProject.value?.endTime))) {
    Message.error('开始时间不能大于截止时间')
    return
  }
  if (type === 'end' && dayjs(value).isBefore(dayjs(currentProject.value?.startTime))) {
    Message.error('截止时间不能早于开始时间')
    return
  }
  try {
    updateProjectRequest.value.id = Number(currentProject.value?.id)
    updateProjectRequest.value.startTime =
      type === 'start' ? dayjs(value).local().format('YYYY-MM-DDTHH:mm:ss') : undefined
    updateProjectRequest.value.endTime =
      type === 'end' ? dayjs(value).local().format('YYYY-MM-DDTHH:mm:ss') : undefined
    const res: any = await updateProjectUsingPost(updateProjectRequest.value)
    if (res.code === 0) {
      // 关闭对应的时间选择器
      if (type === 'start') {
        startTimeVisible.value = false
      } else {
        endTimeVisible.value = false
      }
    } else {
      Message.error(res.message || '更新失败')
    }
  } catch (error) {
    Message.error(`${type === 'start' ? '开始' : '截止'}时间更新失败`)
  } finally {
    // 重置相应的时间字段
    resetUpdateProjectRequest(type === 'start' ? 'startTime' : 'endTime')

    await initData()
  }
}

// 添加获取状态颜色的函数
const getStatusColor = (status: number) => {
  return PROJECT_STATUS_CONFIG[status]?.color || 'var(--color-text-3)'
}

// 添加获取进度条颜色的函数
const getProgressColor = (progress: number) => {
  if (progress >= 100) {
    return 'rgb(var(--success-6))' // 完成 - 绿色
  }
  if (progress >= 70) {
    return 'rgb(var(--primary-6))' // 良好 - 蓝色
  }
  if (progress >= 30) {
    return 'rgb(var(--warning-6))' // 一般 - 黄色
  }
  return 'rgb(var(--danger-6))' // 较差 - 红色
}
//#endregion

//#region 简介备注编辑器
// 添加编辑器实例
const descriptionEditorRef = shallowRef()
const remarkEditorRef = shallowRef()

// 添加编辑状态控制
const isDescriptionEditing = ref(false)
const isRemarkEditing = ref(false)

// 添加编辑器内容
const descriptionHtml = ref(currentProject.value?.description || '')
const remarkHtml = ref(currentProject.value?.remark || '')

// 修改编辑器基础配置
const descriptionEditorConfig = {
  readOnly: true,
  scroll: true,
  autoFocus: false,
  MENU_CONF: {},
  placeholder: '暂无内容',
  maxLength: 300, // 添加最大字符限制
  onMaxLength: () => {
    Message.warning('简介内容最多300个字符')
  }
}

const remarkEditorConfig = {
  readOnly: true,
  scroll: true,
  autoFocus: false,
  MENU_CONF: {},
  placeholder: '暂无内容',
  customAlert: (s: string, t: string) => {
    // 禁用编辑器的默认警告
  }
}

// 修改编辑器创建后的处理函数
const handleProjectDescriptionEditorCreated = (editor: any) => {
  if (editor) {
    descriptionEditorRef.value = editor
    if (!isDescriptionEditing.value) {
      editor.disable()
    }
  }
}

const handleProjectRemarkEditorCreated = (editor: any) => {
  if (editor) {
    remarkEditorRef.value = editor
    if (!isRemarkEditing.value) {
      editor.disable()
    }
  }
}

// 编辑器样式配置
const editorStyle = {
  minHeight: '300px', // 减小编辑器高度
  height: '400px', // 减小编辑器高度
  maxHeight: '640px', // 增加最大高度
  overflow: 'auto'
}

// 监听编辑状态变化
watch(isDescriptionEditing, (newVal) => {
  const editor = descriptionEditorRef.value
  if (editor) {
    if (newVal) {
      editor.enable()
    } else {
      editor.disable()
    }
  }
})

watch(isRemarkEditing, (newVal) => {
  const editor = remarkEditorRef.value
  if (editor) {
    if (newVal) {
      editor.enable()
    } else {
      editor.disable()
    }
  }
})

// 监听 currentProject 的变化来更新编辑器内容
watch(
  () => currentProject.value,
  (newVal) => {
    descriptionHtml.value = newVal?.description || ''
  },
  { immediate: true }
)

watch(
  () => currentProject.value,
  (newVal) => {
    remarkHtml.value = newVal?.remark || ''
  },
  { immediate: true }
)

// 简介编辑状态切换
const handleEditDescription = () => {
  if (isDescriptionEditing.value) {
    // 保存操作
    handleSaveDescription()
  } else {
    // 进入编辑模式
    isDescriptionEditing.value = true
  }
}
// 退出简介编辑
const handleCancelDescription = () => {
  if (descriptionEditorRef.value) {
    descriptionEditorRef.value.disable()
  }
  isDescriptionEditing.value = false
  descriptionHtml.value = currentProject.value?.description || ''
}
// 简介保存
const handleSaveDescription = async () => {
  // 添加字符长度检查
  const textLength = descriptionHtml.value.replace(/<[^>]+>/g, '').length
  if (textLength > 300) {
    Message.error('简介内容不能超过300个字符')
    return
  }

  try {
    updateProjectRequest.value.id = Number(currentProject.value?.id)
    updateProjectRequest.value.description = descriptionHtml.value
    const res: any = await updateProjectUsingPost(updateProjectRequest.value)
    if (res.code === 0) {
    } else {
      Message.error(res.message || '更新失败')
    }
  } catch (error) {
    Message.error('简介更新失败')
  } finally {
    resetUpdateProjectRequest('description')
    isDescriptionEditing.value = false

    await initData()
  }
}

// 备注编辑状态切换
const handleEditRemark = () => {
  if (isRemarkEditing.value) {
    // 保存操作
    handleSaveRemark()
  } else {
    // 进入编辑模式
    isRemarkEditing.value = true
  }
}
// 退出备注编辑
const handleCancelRemark = () => {
  if (remarkEditorRef.value) {
    remarkEditorRef.value.disable()
  }
  isRemarkEditing.value = false
  remarkHtml.value = currentProject.value?.remark || ''
}
// 备注保存
const handleSaveRemark = async () => {
  try {
    updateProjectRequest.value.id = Number(currentProject.value?.id)
    updateProjectRequest.value.remark = remarkHtml.value
    const res: any = await updateProjectUsingPost(updateProjectRequest.value)
    if (res.code === 0) {
    } else {
      Message.error(res.message || '更新失败')
    }
  } catch (error) {
    Message.error('备注更新失败')
  } finally {
    resetUpdateProjectRequest('remark') // 重置 remark 字段
    isRemarkEditing.value = false

    await initData()
  }
}
//#endregion

//#region 成员编辑
// 添加成员编辑相关的状态
const memberEditVisible = ref(false)
const editingMember = ref<any>(null)
const editingRole = ref(0) // 默认为普通成员

// 添加标签选项
const tagOptions = [
  { label: 'UI设计', value: 'UI设计' },
  { label: '前端开发', value: '前端开发' },
  { label: '后端开发', value: '后端开发' },
  { label: '产品经理', value: '产品经理' },
  { label: '测试', value: '测试' },
  { label: '运维', value: '运维' },
  { label: '项目经理', value: '项目经理' },
  { label: '数据分析', value: '数据分析' }
]

// 添加编辑成员的标签状态
const editingTag = ref('')

// 修改处理成员编辑按钮点击
const handleMemberEdit = (member: any) => {
  editingMember.value = member
  editingRole.value = Number(member.role)
  editingTag.value = member.tag || '' // 设置当前标签
  memberEditVisible.value = true
}

// 修改成员角色更新函数
const handleUpdateMemberRole = async () => {
  try {
    const res: any = await updateUserInProjectUsingPost({
      proId: Number(currentProject.value?.id),
      userId: editingMember.value.id,
      role: editingRole.value !== editingMember.value.role ? editingRole.value : undefined,
      tag: editingTag.value !== editingMember.value.tag ? editingTag.value : undefined
    })

    if (res.code === 0) {
    } else {
      Message.error(res.message || '更新失败')
    }
  } catch (error) {
    Message.error('成员信息更新失败')
  } finally {
    memberEditVisible.value = false

    await initData()
  }
}

// 添加判断是否为项目负责人的计算属性
const isProjectOwner = computed(() => {
  return userStore.user?.id === currentProject.value?.owner?.id
})

// 修改判断是否可以编辑成员的函数
const canEditMember = (memberId: number) => {
  // 项目负责人可以编辑所有人（包括自己）
  if (isProjectOwner.value) {
    return true
  }
  // 项目管理员可以编辑普通成员（除了自己）
  return userInProject?.role === 1 && memberId !== userStore.user?.id
}

// 修改判断是否可以删除成员的函数
const canRemoveMember = (member: any) => {
  // 项目负责人可以删除所有人（除了自己）
  if (isProjectOwner.value && member.userId !== userStore.user?.id) {
    return true
  }
  // 项目管理员只能删除普通成员（除了自己）
  return userInProject?.role === 1 && member.userId !== userStore.user?.id && member.role !== 1
}

// 判断是否可以编辑角色的函数
const canEditRole = computed(() => {
  // 如果是编辑自己，则不能修改角色
  if (editingMember.value?.id === userStore.user?.id) {
    return false
  }
  // 项目负责人可以编辑其他人的角色
  if (isProjectOwner.value) {
    return true
  }
  // 项目管理员只能编辑普通成员的角色
  return userInProject?.role === 1 && editingMember.value?.role !== 1
})
//#endregion

// 添加字符计数显示
const descriptionLength = computed(() => {
  return descriptionHtml.value.replace(/<[^>]+>/g, '').length
})
//#region 附件预览

//组件失活时
onDeactivated(async () => {})
//向上传递
const submitReload = async (refresh: boolean) => {
  await getCurrentProject()
  if (refresh) {
    //刷新页面
    window.location.reload()
  }
}

//#region 获取项目数据
const getCurrentProject = async () => {
  try {
    const res: any = await getProjectUsingGet({
      id: props.proId
    })
    if (res.code === 0) {
      currentProject.value = res.data
    } else {
      Message.error(res.msg || '获取项目信息失败')
    }
  } catch (error) {
    console.error('获取项目信息失败:', error)
    Message.error('获取项目信息失败')
  }
}
//#endregion
// 初始化数据
const initData = async () => {
  if (!props.proId) return
  try {
    await getCurrentProject()
    await Promise.all([
      getProjectTaskCount(),
      getProjectMemberList(),
      loadMoreAttaches(),
      getDynamicList()
    ])
  } catch (error) {
    console.error('初始化数据失败:', error)
  }
}
//#endregion
// 组件激活时重新加载数据
onActivated(async () => {
  await initData()
})
// 确保在组件挂载时调用
onMounted(async () => {
  await initData()
})
</script>

<template>
  <div class="project-overview">
    <!-- 左侧内容区域 -->
    <div class="main-content">
      <!-- 基本信息卡片 -->
      <a-card class="info-card" :class="`status-${projectStatus.value}`">
        <!-- 项目标题行 -->
        <h3 class="card-title">项目信息</h3>
        <br />
        <div class="project-title-row">
          <a-image
            :src="currentProject?.owner?.avatar"
            :preview="false"
            :width="60"
            :height="60"
            fit="cover"
            class="project-icon"
            :fallback="'//p3-armor.byteimg.com/tos-cn-i-49unhts6dw/dfdba5317c0c20ce20e64fac803d52bc.svg~tplv-49unhts6dw-image.image'"
          />
          <div class="project-info">
            <h2 class="project-name">{{ currentProject?.title }}</h2>
            <div class="project-code">{{ currentProject?.code || '暂无编号' }}</div>
          </div>
        </div>

        <!-- 项目详细信息行 -->
        <div class="project-detail-row">
          <!-- 负责人信息 -->
          <a-popover
            title="负责人"
            position="bl"
            trigger="click"
            :disabled="userStore.user.id !== currentProject?.owner?.id"
          >
            <div class="detail-item owner-info">
              <div class="owner-avatar-wrapper">
                <a-avatar :size="32" :image-url="currentProject?.owner?.avatar">
                  {{ currentProject?.owner?.name?.[0] || '?' }}
                </a-avatar>
              </div>
              <div class="owner-text">
                <span class="owner-name">{{ currentProject?.owner?.name }}</span>
                <span class="owner-role">负责人</span>
              </div>
            </div>

            <!-- 弹出内容 -->
            <template #content>
              <div class="owner-select-popup">
                <div
                  v-for="member in projectMemberList"
                  :key="member.userId"
                  class="owner-select-item"
                  @click="handleOwnerSelect(member)"
                >
                  <div class="member-info">
                    <a-avatar :size="28" :image-url="member.avatar">
                      {{ member.name?.[0] || '?' }}
                    </a-avatar>
                    <span class="member-name">{{ member.name }}</span>
                    <a-tag v-if="member.userId === userStore.user.id" size="small"> 我自己 </a-tag>
                  </div>
                  <icon-check
                    v-if="member.userId === currentProject?.owner?.id"
                    class="selected-icon"
                  />
                </div>
              </div>
            </template>
          </a-popover>

          <!-- 开始时间 -->
          <a-popover
            position="bottom"
            trigger="click"
            :disabled="userStore.user.id !== currentProject?.owner?.id"
            :popup-visible="startTimeVisible"
            @popup-visible-change="(visible) => (startTimeVisible = visible)"
          >
            <div class="detail-item time-item">
              <div class="time-icon-wrapper">
                <icon-calendar-clock class="time-icon" :stroke-width="2" :stroke-dasharray="4" />
              </div>
              <div class="time-info">
                <span class="time-label">开始时间</span>
                <span class="time-value">{{
                  dayjs(currentProject?.startTime).format('YYYY-MM-DD')
                }}</span>
              </div>
            </div>

            <template #content>
              <a-date-picker
                hide-trigger
                show-time
                format="YYYY-MM-DD HH:mm:ss"
                :default-value="dayjs(currentProject?.startTime)"
                :popup-visible="false"
                @change="(value) => handleTimeChange('start', value)"
              />
            </template>
          </a-popover>

          <!-- 截止时间 -->
          <a-popover
            position="bottom"
            trigger="click"
            :disabled="userStore.user.id !== currentProject?.owner?.id"
            :popup-visible="endTimeVisible"
            @popup-visible-change="(visible) => (endTimeVisible = visible)"
          >
            <div class="detail-item time-item">
              <div class="time-icon-wrapper">
                <icon-calendar class="time-icon" :stroke-width="2" :stroke-dasharray="4" />
              </div>
              <div class="time-info">
                <span class="time-label">截止时间</span>
                <span class="time-value">{{
                  dayjs(currentProject?.endTime).format('YYYY-MM-DD')
                }}</span>
              </div>
            </div>

            <template #content>
              <a-date-picker
                hide-trigger
                show-time
                format="YYYY-MM-DD HH:mm:ss"
                :default-value="dayjs(currentProject?.endTime)"
                :popup-visible="false"
                @change="(value) => handleTimeChange('end', value)"
              />
            </template>
          </a-popover>

          <!-- 延期状态 -->
          <div class="detail-item delay-status">
            <a-tag :color="currentProject?.canDelay ? 'green' : 'red'">
              {{ currentProject?.canDelay ? '宽松' : '严格' }}
            </a-tag>
          </div>
        </div>
      </a-card>

      <!-- 成员卡片 -->
      <a-card class="members-card">
        <div class="card-header">
          <h3>成员</h3>
          <a-button type="text" size="mini" @click="handleAddMember">
            <icon-plus />
          </a-button>
        </div>

        <!-- 搜索和统计行 -->
        <div class="search-bar">
          <a-input-search
            v-model="searchKeyword"
            placeholder="搜索成员"
            :style="{ width: '200px' }"
            size="small"
            @search="handleSearchMember"
          >
            <template #prefix>
              <icon-search />
            </template>
          </a-input-search>
          <span class="member-count"> 共 {{ currentProject?.members?.length || 0 }} 名成员 </span>
        </div>

        <!-- 添加成员选择对话框 -->
        <a-modal
          v-model:visible="memberSelectVisible"
          title="添加成员"
          @ok="handleConfirmAddMembers"
          @cancel="memberSelectVisible = false"
        >
          <div class="member-select-content">
            <div class="member-select-list">
              <div v-for="user in teamUserVoList" :key="user.id" class="member-select-item">
                <a-checkbox
                  :model-value="selectedUsers.includes(Number(user.id))"
                  :disabled="isProjectMember(Number(user.id))"
                  @change="(checked) => handleMemberSelect(Number(user.id), checked)"
                >
                  <div class="member-info">
                    <a-avatar :size="28" :image-url="user.avatar">
                      {{ user.name?.[0] || '?' }}
                    </a-avatar>
                    <span class="member-name">{{ user.name }}</span>
                    <a-tag v-if="isProjectMember(Number(user.id))" size="small">已是成员</a-tag>
                  </div>
                </a-checkbox>
              </div>
            </div>
          </div>
        </a-modal>

        <!-- 成员表格 -->
        <a-table :data="projectMemberList || []" :pagination="false" :bordered="false" size="small">
          <!-- 添加序号列 -->
          <template #columns>
            <a-table-column title="序号" align="center" :width="70">
              <template #cell="{ rowIndex }">
                {{ rowIndex + 1 }}
              </template>
            </a-table-column>

            <!-- 成员列 -->
            <a-table-column title="成员" align="left">
              <template #cell="{ record }">
                <div class="member-info">
                  <a-avatar :size="32" :image-url="record.avatar">
                    {{ record.name?.[0] || '?' }}
                  </a-avatar>
                  <span class="member-name">{{ record.name }}</span>
                </div>
              </template>
            </a-table-column>

            <!-- 角色列 -->
            <a-table-column title="角色" align="center">
              <template #cell="{ record }">
                <a-tag :color="record.role === 1 ? 'arcoblue' : ''">
                  {{ record.role === 1 ? '管理员' : '成员' }}
                </a-tag>
              </template>
            </a-table-column>

            <!-- 标签列 -->
            <a-table-column title="标签" align="center">
              <template #cell="{ record }">
                <a-tag v-if="record.tag" color="green">{{ record.tag }}</a-tag>
                <span v-else>-</span>
              </template>
            </a-table-column>

            <!-- 操作列 -->
            <a-table-column title="操作" align="center" :width="150">
              <template #cell="{ record }">
                <a-space>
                  <a-button
                    v-if="canEditMember(record.id)"
                    type="text"
                    size="small"
                    @click="handleMemberEdit(record)"
                  >
                    <template #icon>
                      <a-button type="text" size="small"> <icon-edit />编辑 </a-button>
                    </template>
                  </a-button>
                  <a-button
                    v-if="canRemoveMember(record)"
                    type="text"
                    status="danger"
                    size="small"
                    @click="handleRemoveMember(record)"
                  >
                    移除
                  </a-button>
                </a-space>
              </template>
            </a-table-column>
          </template>
        </a-table>
      </a-card>

      <!-- 更新组件使用 -->
      <MilestoneTasksList
        :project-vo="currentProject"
        @reload="(refresh) => submitReload(refresh)"
      />

      <!-- 附件卡片 -->
      <a-card class="attachments-card">
        <div class="card-header">
          <h3>附件</h3>
          <div class="upload-wrapper">
            <a-upload
              :custom-request="handleUpload"
              :show-file-list="false"
              @before-upload="beforeUpload"
            >
              <template #upload-button>
                <a-space>
                  <span class="upload-tip">
                    <icon-info-circle /> <span>{{ '文件大小 < 10MB' }}</span>
                  </span>
                  <a-button type="text" size="mini">
                    <template #icon>
                      <icon-plus />
                    </template>
                    上传附件
                  </a-button>
                </a-space>
              </template>
            </a-upload>
          </div>
        </div>

        <!-- 文件列表表格 -->
        <a-table
          :data="allAttaches"
          :pagination="false"
          :bordered="false"
          size="small"
          :loading="fileLoading"
        >
          <!-- 添加序号列 -->
          <template #columns>
            <a-table-column title="序号" align="center" :width="70">
              <template #cell="{ rowIndex }">
                {{ rowIndex + 1 }}
              </template>
            </a-table-column>

            <!-- 文件名列 -->
            <a-table-column title="附件名" align="left" :width="200">
              <template #cell="{ record }">
                <div class="file-name">
                  <component :is="getFileIcon(record.name)" class="file-icon" />
                  <span>{{ record.name }}</span>
                </div>
              </template>
            </a-table-column>

            <!-- 文件大小列 -->
            <a-table-column title="大小" align="center" :width="120">
              <template #cell="{ record }">
                {{ formatFileSize(record.size) }}
              </template>
            </a-table-column>

            <!-- 上传人列 -->
            <a-table-column title="上传人" align="center" :width="120">
              <template #cell="{ record }">
                <div class="uploader-info">
                  <a-avatar :size="24" :image-url="record.uploader.avatar">
                    {{ record.uploader.name?.[0] }}
                  </a-avatar>
                  <span>{{ record.uploader.name }}</span>
                </div>
              </template>
            </a-table-column>

            <!-- 上传时间列 -->
            <a-table-column title="上传时间" align="center" :width="160">
              <template #cell="{ record }">
                {{ dayjs(record.createAt).format('YYYY-MM-DD HH:mm:ss') }}
              </template>
            </a-table-column>

            <!-- 操作列 -->
            <a-table-column title="操作" align="center" :width="120">
              <template #cell="{ record }">
                <a-space>
                  <!-- 添加预览按钮 -->
                  <a-button
                    v-if="getFileType(record.extension) !== 'other'"
                    type="text"
                    size="small"
                    @click="handlePreview(record)"
                  >
                    <icon-eye />预览
                  </a-button>
                  <a-button type="text" size="small" @click="downloadFile(record)">
                    <icon-download />下载
                  </a-button>
                  <a-button
                    type="text"
                    status="danger"
                    size="small"
                    @click="handleDeleteAttache(record)"
                  >
                    <icon-delete />删除
                  </a-button>
                </a-space>
              </template>
            </a-table-column>
          </template>
        </a-table>
        <!-- 加载更多按钮 -->
        <div v-if="hasMoreAttaches" class="load-more">
          <a-button
            type="text"
            size="small"
            :loading="fileLoading"
            @click="
              async () => {
                await loadMoreAttaches()
              }
            "
          >
            加载更多
          </a-button>
        </div>
      </a-card>
    </div>

    <!-- 右侧信息面板 -->
    <div class="info-panel">
      <!-- 状态信息部分 -->
      <a-card class="status-section">
        <h3 class="section-title">状态信息</h3>
        <div class="status-content">
          <div class="status-item">
            <span class="label">当前状态</span>
            <template v-if="showStatusSelect">
              <!-- 正常状态下显示选择器 -->
              <a-select
                v-model="projectStatus"
                size="small"
                :style="{ width: '100%' }"
                :disabled="isStatusSelectDisabled"
                @change="handleStatusChange"
              >
                <a-option v-for="status in statusList" :key="status.value" :value="status.value">
                  <div class="status-option">
                    <div class="status-dot" :style="{ backgroundColor: status.color }"></div>
                    {{ status.label }}
                  </div>
                </a-option>
              </a-select>
            </template>
            <template v-else>
              <!-- 已逾期状态下显示文本 -->
              <div class="status-display">
                <div class="status-option">
                  <div
                    class="status-dot"
                    :style="{ backgroundColor: PROJECT_STATUS_CONFIG[ProjectStatus.OVERDUE].color }"
                  ></div>
                  {{ currentStatusText }}
                </div>
              </div>
            </template>
          </div>

          <!-- 修改进度条部分 -->
          <div class="status-item">
            <span class="label">项目进度</span>
            <div class="progress-wrapper">
              <a-progress
                :percent="currentProject?.progress || 0"
                :stroke-color="getProgressColor(currentProject?.progress || 0)"
                track-color="var(--color-fill-2)"
                size="small"
                :animation="true"
                :style="{
                  '--progress-track-color': 'var(--color-fill-2)',
                  '--progress-color': getProgressColor(currentProject?.progress || 0)
                }"
              />
            </div>
          </div>
        </div>
      </a-card>
      <div class="divider"></div>

      <!-- 任务统计部分 -->
      <a-card class="task-stats-section">
        <h3 class="section-title">任务统计</h3>
        <div class="stats-grid">
          <!-- 第一行统计 -->
          <div class="stats-row">
            <div class="stats-item">
              <div class="stats-label">任务总数</div>
              <div class="stats-value">{{ taskCount?.totalTask }}</div>
            </div>
            <div class="stats-item">
              <div class="stats-label">已完成</div>
              <div class="stats-value success">{{ taskCount?.doneTask }}</div>
            </div>
            <div class="stats-item">
              <div class="stats-label">进行中</div>
              <div class="stats-value primary">{{ taskCount?.doingTask }}</div>
            </div>
          </div>

          <!-- 第二行统计 -->
          <div class="stats-row">
            <div class="stats-item">
              <div class="stats-label">未开始</div>
              <div class="stats-value">{{ taskCount?.unStartTask }}</div>
            </div>
            <div class="stats-item">
              <div class="stats-label">延期任务</div>
              <div class="stats-value danger">{{ taskCount?.overdueTask }}</div>
            </div>
            <div class="stats-item">
              <div class="stats-label">今日到期</div>
              <div class="stats-value warning">{{ taskCount?.todayTask }}</div>
            </div>
          </div>

          <!-- 第三行：完成率和延期率 -->
          <div class="rate-row">
            <div class="rate-item">
              <div class="rate-label">完成率</div>
              <div class="rate-value success">
                {{ Number((taskCount?.process || 0) * 100).toFixed(2) }}%
              </div>
            </div>
            <div class="rate-item">
              <div class="rate-label">延期率</div>
              <div class="rate-value danger">
                {{ (taskCount?.overDueRate * 100).toFixed(1) || 0 }}%
              </div>
            </div>
          </div>
        </div>
      </a-card>
      <div class="divider"></div>
      <!-- 项目简介卡片 -->
      <a-card class="description-section">
        <div class="section-header">
          <h3 class="section-title">项目简介</h3>
          <div class="button-group" v-if="userInProject?.role === 1">
            <template v-if="isDescriptionEditing">
              <a-button type="outline" status="danger" size="mini" @click="handleCancelDescription">
                <template #icon>
                  <icon-close />
                </template>
                取消
              </a-button>
              <a-button type="text" size="mini" @click="handleSaveDescription">
                <template #icon>
                  <icon-check />
                </template>
                保存
              </a-button>
            </template>
            <a-button v-else type="text" size="mini" @click="handleEditDescription">
              <template #icon>
                <icon-edit />
              </template>
              编辑
            </a-button>
          </div>
        </div>
        <div class="description-content">
          <Toolbar
            v-show="isDescriptionEditing"
            class="toolbar"
            :editor="descriptionEditorRef"
            :mode="'simple'"
          />
          <Editor
            class="editor"
            v-model="descriptionHtml"
            :defaultConfig="editorConfig"
            :mode="'simple'"
            :style="editorStyle"
            @onCreated="handleProjectDescriptionEditorCreated"
          />
          <!-- 添加字符计数显示 -->
          <div v-if="isDescriptionEditing" class="char-count">{{ descriptionLength }}/300</div>
        </div>
      </a-card>

      <div class="divider"></div>

      <!-- 项目备注卡片 -->
      <a-card class="remark-section">
        <div class="section-header">
          <h3 class="section-title">项目备注</h3>
          <div class="button-group" v-if="userInProject?.role === 1">
            <template v-if="isRemarkEditing">
              <a-button type="outline" status="danger" size="mini" @click="handleCancelRemark">
                <template #icon>
                  <icon-close />
                </template>
                取消
              </a-button>
              <a-button type="text" size="mini" @click="handleSaveRemark">
                <template #icon>
                  <icon-check />
                </template>
                保存
              </a-button>
            </template>
            <a-button v-else type="text" size="mini" @click="handleEditRemark">
              <template #icon>
                <icon-edit />
              </template>
              编辑
            </a-button>
          </div>
        </div>
        <div class="remark-content">
          <Toolbar
            v-show="isRemarkEditing"
            class="toolbar"
            :editor="remarkEditorRef"
            :mode="'simple'"
          />
          <Editor
            class="editor"
            v-model="remarkHtml"
            :defaultConfig="editorConfig"
            :mode="'simple'"
            :style="editorStyle"
            @onCreated="handleProjectRemarkEditorCreated"
          />
        </div>
      </a-card>

      <div class="divider"></div>
      <!-- 项目动态部分 -->
      <a-card class="activity-section">
        <h3 class="section-title">项目动态</h3>
        <div class="activity-list">
          <a-spin :loading="dynamicLoading">
            <template v-if="dynamicList.length > 0">
              <div v-for="(dynamic, index) in dynamicList" :key="dynamic.id" class="activity-item">
                <div class="activity-content">
                  <!-- 添加序号 -->
                  <span class="activity-index">{{ index + 1 }}</span>

                  <!-- 操作者信息 -->
                  <div class="activity-user">
                    <a-avatar :size="28" :image-url="dynamic.operator?.avatar">
                      {{ dynamic.operator?.username?.[0]?.toUpperCase() }}
                    </a-avatar>
                    <span class="user-name">{{ dynamic.operator?.username }}</span>
                  </div>

                  <!-- 动态内容 -->
                  <div class="activity-message">
                    {{ dynamic.content }}
                  </div>

                  <!-- 时间 -->
                  <div class="activity-time">
                    {{ dayjs(dynamic.createAt).format('MM-DD HH:mm') }}
                  </div>
                </div>
              </div>

              <!-- 加载更多按钮 -->
              <div v-if="hasMoreDynamic" class="load-more">
                <a-button
                  type="text"
                  size="small"
                  :loading="dynamicLoading"
                  @click="handleLoadMoreDynamic"
                >
                  加载更多
                </a-button>
              </div>
            </template>
            <a-empty v-else description="暂无动态" />
          </a-spin>
        </div>
      </a-card>
    </div>

    <!-- 添加成员编辑对话框 -->
    <a-modal
      v-model:visible="memberEditVisible"
      title="编辑成员信息"
      @cancel="memberEditVisible = false"
      @ok="handleUpdateMemberRole"
      :ok-loading="false"
    >
      <div class="member-edit-content">
        <!-- 成员基本信息 -->
        <div class="member-info">
          <a-avatar :size="32" :image-url="editingMember?.avatar">
            {{ editingMember?.username?.[0]?.toUpperCase() }}
          </a-avatar>
          <span class="member-name">{{ editingMember?.username }}</span>
        </div>

        <!-- 角色选择 - 只在可以编辑角色时显示 -->
        <div class="edit-section" v-if="canEditRole">
          <div class="section-label">角色</div>
          <a-radio-group v-model="editingRole">
            <a-radio :value="0">成员</a-radio>
            <a-radio :value="1">管理员</a-radio>
          </a-radio-group>
        </div>

        <!-- 标签选择 - 始终显示 -->
        <div class="edit-section">
          <div class="section-label">标签</div>
          <a-select
            v-model="editingTag"
            placeholder="请选择或输入标签"
            allow-clear
            allow-create
            :options="tagOptions"
            style="width: 100%"
            :max-tag-count="1"
          />
        </div>
      </div>
    </a-modal>

    <!-- 预览组件 -->
    <FilePreview v-model:isPreviewOpen="previewVisible" :file="previewFile" @close="closePreview" />
  </div>
</template>

<style scoped>
/* 修改主容器样式 */
.project-overview {
  display: flex;
  gap: 12px;
  padding: 0;
  flex-wrap: wrap; /* 允许换行 */
  min-width: 320px; /* 设置最小宽度 */
}

/* 修改主内容区域样式 */
.main-content {
  flex: 7; /* 占据7份空间 */
  min-width: 600px; /* 设置最小宽度 */
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* 修改信息面板样式 */
.info-panel {
  flex: 3; /* 占据3份空间 */
  min-width: 300px; /* 设置最小宽度 */
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* 添加响应式布局 */
@media screen and (max-width: 1200px) {
  .project-overview {
    flex-direction: column; /* 变成上下布局 */
  }

  .main-content,
  .info-panel {
    flex: none; /* 取消 flex 比例 */
    width: 100%; /* 占满宽度 */
    min-width: 320px; /* 重置最小宽度 */
  }
}

/* 修改卡片样式 */
.info-card,
.members-card,
.milestone-card,
.files-card,
.status-section,
.task-stats-section,
.activity-section {
  width: 100%; /* 占满容器宽度 */
  background: var(--color-bg-2);
  border-radius: 4px;
  padding: 20px;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.05);
  box-sizing: border-box; /* 确保 padding 不会增加宽度 */
}

/* 添加卡片内容自适应 */
.card-content {
  width: 100%;
  overflow-x: auto; /* 允许横向滚动 */
  min-width: 0; /* 允许内容收缩 */
}

/* 表格容器样式 */
.table-container {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch; /* 提升移动端滚动体验 */
}

/* 确保表格不会溢出 */
:deep(.arco-table) {
  min-width: 600px; /* 设置最小宽度 */
}

/* 优化小屏幕上的间距 */
@media screen and (max-width: 768px) {
  .project-overview {
    gap: 16px;
    padding: 12px;
  }

  .main-content {
    gap: 16px;
  }

  .info-card,
  .members-card,
  .milestone-card,
  .files-card,
  .status-section,
  .task-stats-section,
  .activity-section {
    padding: 16px;
  }
}

/* 优化超小屏幕上的显示 */
@media screen and (max-width: 480px) {
  .project-overview {
    gap: 12px;
    padding: 8px;
  }

  .main-content {
    gap: 12px;
  }

  .info-card,
  .members-card,
  .milestone-card,
  .files-card,
  .status-section,
  .task-stats-section,
  .activity-section {
    padding: 12px;
  }
}

.activity-section {
  margin-top: 16px;
}

.activity-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.activity-item {
  padding: 12px 0;
  border-bottom: 1px solid var(--color-border);
}

.activity-item:last-child {
  border-bottom: none;
}

.activity-content {
  display: flex;
  align-items: flex-start; /* 改为顶部对齐 */
  gap: 12px;
}

/* 序号样式 */
.activity-index {
  min-width: 30px; /* 固定宽度 */
  color: var(--color-text-3);
  font-size: 13px;
  text-align: right;
  padding-top: 4px; /* 微调对齐 */
}

/* 用户信息样式 */
.activity-user {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 120px; /* 固定宽度 */
  flex-shrink: 0; /* 防止压缩 */
}

.activity-user .user-name {
  font-size: 13px;
  color: var(--color-text-2);
  white-space: nowrap; /* 防止换行 */
  overflow: hidden;
  text-overflow: ellipsis; /* 超出显示省略号 */
  max-width: 80px; /* 限制最大宽度 */
}

/* 动态内容样式 */
.activity-message {
  flex: 1; /* 占据剩余空间 */
  font-size: 14px;
  color: var(--color-text-1);
  line-height: 1.6;
  padding-top: 4px; /* 微调对齐 */
  word-break: break-all; /* 允许在任意字符间断行 */
}

/* 时间样式 */
.activity-time {
  min-width: 90px; /* 固定宽度 */
  font-size: 13px;
  color: var(--color-text-3);
  text-align: right;
  padding-top: 4px; /* 微调对齐 */
  flex-shrink: 0; /* 防止压缩 */
}

/* 头像样式优化 */
:deep(.arco-avatar) {
  flex-shrink: 0; /* 防止压缩 */
}

/* 响应式调整 */
@media screen and (max-width: 768px) {
  .activity-user {
    min-width: 100px;
  }

  .activity-time {
    min-width: 70px;
  }

  .activity-user .user-name {
    max-width: 60px;
  }
}

.load-more {
  display: flex;
  justify-content: center;
  padding: 16px 0 0;
}

.project-title-row {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 12px;
}

.project-name {
  margin: 0;
  font-size: 20px;
  font-weight: 500;
  color: var(--color-text-1);
}

.project-detail-row {
  display: grid;
  grid-template-columns: 3fr 3fr 3fr 1fr; /* 3:3:3:1 的比例 */
  align-items: center;
  padding: 16px 0;
  border-top: 1px solid var(--color-border);
  gap: 16px;
}

.detail-item {
  min-width: 0; /* 允许内容收缩 */
}

.owner-info {
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  transition: all 0.2s;
}

.owner-info:hover {
  background-color: var(--color-fill-2);
}

.owner-avatar-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%; /* 保持头像圆形 */
  background-color: var(--color-fill-2);
  transition: all 0.2s;
}

.owner-info:hover .owner-avatar-wrapper {
  background-color: var(--color-fill-3);
}

.owner-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.owner-name {
  font-size: 14px;
  color: var(--color-text-1);
  line-height: 1.4;
}

.owner-role {
  font-size: 12px;
  color: var(--color-text-3);
  line-height: 1.4;
}

.time-item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  transition: all 0.2s;
}

.time-item:hover {
  background-color: var(--color-fill-2);
}

.time-icon-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background-color: var(--color-fill-2);
  transition: all 0.2s;
  cursor: pointer;
}

.time-icon-wrapper:hover {
  background-color: var(--color-fill-3);
}

.time-icon {
  font-size: 24px;
  color: rgb(var(--primary-6));
}

.time-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.time-label {
  font-size: 13px;
  color: var(--color-text-3);
  line-height: 1.4;
}

.time-value {
  font-size: 14px;
  color: var(--color-text-1);
  line-height: 1.4;
}

.delay-status {
  display: flex;
  justify-content: flex-end; /* 右对齐 */
}

.project-icon {
  border-radius: 4px;
  overflow: hidden;
  flex-shrink: 0;
}

.project-code {
  font-size: 13px;
  color: var(--color-text-3);
  line-height: 1.4;
  opacity: 0.8;
}

.members-card {
  background: var(--color-bg-2);
  border-radius: 4px;
  padding: 20px;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.05);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.card-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
  color: var(--color-text-1);
}

.search-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 16px 0;
  padding: 0 4px;
}

.member-count {
  font-size: 13px;
  color: var(--color-text-3);
}

.member-info {
  display: flex;
  align-items: center;
  gap: 12px;
}

.member-name {
  font-size: 14px;
  color: var(--color-text-1);
}

:deep(.arco-table-th) {
  background-color: var(--color-fill-2) !important;
  font-weight: 500;
}

:deep(.arco-table-tr) {
  cursor: pointer;
}

:deep(.arco-table-tr:hover) {
  background-color: var(--color-fill-2);
}

:deep(.arco-btn-text) {
  padding: 0 4px;
}

.milestone-card {
  background: transparent;
  box-shadow: none;
  padding: 12px 0;
  border: none;
}

.milestone-item {
  padding: 8px 0;
}

.milestone-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  background-color: rgba(64, 128, 255, 0.15);
  border-left: 4px solid rgb(64, 128, 255);
}

.milestone-title {
  font-size: 15px;
  font-weight: 500;
  color: var(--color-text-1);
}

.milestone-date {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--color-text-3);
  font-size: 13px;
  margin-bottom: 12px;
}

.milestone-progress {
  margin-top: 8px;
}

.progress-text {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  color: var(--color-text-2);
  margin-bottom: 4px;
}

.tasks-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  font-size: 13px;
  color: var(--color-text-2);
}

.task-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 0;
}

.completed {
  text-decoration: line-through;
  color: var(--color-text-3);
}

:deep(.arco-timeline) {
  padding: 8px 0;
}

:deep(.arco-timeline-item-content) {
  padding-bottom: 24px;
}

.files-card {
  background: var(--color-bg-2);
  border-radius: 4px;
  padding: 20px;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.05);
}

.file-name {
  display: flex;
  align-items: center;
  gap: 8px;
}

.file-icon {
  font-size: 20px;
  color: var(--color-text-3);
}

.uploader-info {
  display: flex;
  align-items: center;
  gap: 8px;
}

:deep(.arco-upload-wrapper) {
  display: inline-block;
}

:deep(.arco-btn-text) {
  padding: 0 4px;
}

.section-title {
  margin: 0 0 16px 0;
  font-size: 16px;
  font-weight: 500;
  color: var(--color-text-1);
}

.status-section {
  padding: 20px;
}

.status-content {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.status-item {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.label {
  font-size: 13px;
  color: var(--color-text-2);
}

.divider {
  height: 1px;
  background-color: var(--color-border);
  margin: 0;
}

.status-option {
  display: flex;
  align-items: center;
  gap: 8px;
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

:deep(.arco-select-view) {
  background-color: var(--color-fill-2);
  border-radius: 4px;
}

:deep(.arco-select-view-value) {
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
}

:deep(.arco-select-view-value::before) {
  content: '';
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: v-bind('PROJECT_STATUS_CONFIG[projectStatus]?.color');
}

:deep(.arco-select:hover .arco-select-view) {
  background-color: var(--color-fill-3);
}

.task-stats-section {
  padding: 20px;
}

.stats-grid {
  display: flex;
  flex-direction: column;
  gap: 24px;
  margin-top: 16px;
}

.stats-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

.stats-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.stats-label {
  font-size: 13px;
  color: var(--color-text-2);
  white-space: nowrap;
}

.stats-value {
  font-size: 20px;
  font-weight: 600;
  color: var(--color-text-1);
}

.stats-value.primary {
  color: rgb(var(--primary-6));
}

.stats-value.success {
  color: rgb(var(--success-6));
}

.stats-value.warning {
  color: rgb(var(--warning-6));
}

.stats-value.danger {
  color: rgb(var(--danger-6));
}

.rate-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-top: 8px; /* 与上面的统计保持一定间距 */
  padding-top: 16px;
  border-top: 1px solid var(--color-border); /* 添加分隔线 */
}

.rate-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.rate-label {
  font-size: 13px;
  color: var(--color-text-2);
  white-space: nowrap;
}

.rate-value {
  font-size: 20px;
  font-weight: 600;
  color: var(--color-text-1);
}

.rate-value.success {
  color: rgb(var(--success-6));
}

.rate-value.danger {
  color: rgb(var(--danger-6));
}

.load-more-files {
  display: flex;
  justify-content: center;
  padding: 16px 0 8px;
  border-top: 1px solid var(--color-border);
  margin-top: 16px;
}

.load-more-files .arco-btn {
  color: var(--color-text-3);
}

.load-more-files .arco-btn:hover {
  color: rgb(var(--primary-6));
}

.owner-select-popup {
  min-width: 240px; /* 增加最小宽度 */
  background: var(--color-bg-2);
  border-radius: 4px;
  padding: 4px;
}

.owner-select-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px; /* 增加内边距 */
  cursor: pointer;
  border-radius: 4px;
  transition: all 0.2s;
  min-height: 48px; /* 设置最小高度，与负责人项匹配 */
}

.owner-select-item .member-info {
  flex: 1; /* 让成员信息占据更多空间 */
  gap: 12px; /* 增加间距 */
}

.owner-select-item .member-name {
  font-size: 14px;
  color: var(--color-text-1);
  flex: 1; /* 让名字占据剩余空间 */
}

.selected-icon {
  color: rgb(var(--primary-6));
  font-size: 16px;
}

/* 添加成员选择相关样式 */
.member-select-content {
  max-height: 400px;
  overflow-y: auto;
}

.member-select-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.member-select-item {
  padding: 8px;
  border-radius: 4px;
  transition: background-color 0.2s;
}

.member-select-item:hover {
  background-color: var(--color-fill-2);
}

.member-select-item .member-info {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-left: 8px;
}

.member-select-item .member-name {
  font-size: 14px;
  color: var(--color-text-1);
}

:deep(.arco-checkbox) {
  display: flex;
  align-items: center;
}

:deep(.arco-checkbox-disabled) {
  cursor: not-allowed;
  opacity: 0.7;
}

.progress-wrapper {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 4px 0;
}

.progress-text {
  font-size: 14px;
  font-weight: 500;
  min-width: 48px;
}

:deep(.arco-progress) {
  flex: 1;
}

:deep(.arco-progress-line-track) {
  background-color: var(--progress-track-color) !important;
}

:deep(.arco-progress-line-path) {
  background-color: var(--progress-color) !important;
  transition: all 0.3s ease;
}

.description-section,
.remark-section {
  padding: 16px 20px;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.description-content,
.remark-content {
  display: flex;
  flex-direction: column;
  gap: 2px;
  background-color: var(--color-fill-2);
  border-radius: 4px;
  padding: 12px;
}

/* 修改编辑器内容区域样式 */
:deep(.w-e-text-container) {
  cursor: text !important;
}

:deep(.w-e-text-container *) {
  user-select: text !important;
  -webkit-user-select: text !important;
  -moz-user-select: text !important;
  -ms-user-select: text !important;
}

:deep(.w-e-text) {
  padding: 0 10px;
  cursor: text !important;
}

/* 编辑区域样式 */
:deep(.w-e-scroll) {
  padding: 0 !important;
  overflow-y: auto !important;
  scrollbar-width: none !important; /* Firefox */
  -ms-overflow-style: none !important; /* IE and Edge */
}

/* 隐藏 Webkit 浏览器的滚动条 */
:deep(.w-e-scroll::-webkit-scrollbar) {
  display: none !important;
}

/* 编辑器内容区域样式 */
:deep(.w-e-text-html) {
  padding: 0 !important;
  user-select: text !important;
  cursor: text !important;
}

.button-group {
  display: flex;
  gap: 8px;
}

/* 添加链接样式 */
:deep(.w-e-text-container a) {
  color: rgb(var(--primary-6)) !important;
  text-decoration: none !important;
}

:deep(.w-e-text-container a:hover) {
  text-decoration: underline !important;
}

/* 添加工具栏样式 */
.editor-toolbar {
  position: sticky;
  top: 0;
  z-index: 100;
  background-color: var(--color-bg-2);
  border-bottom: 1px solid var(--color-border);
  padding: 8px;
  margin-bottom: 16px;
}
:deep(.toolbar) {
  background-color: var(--color-fill-2);
  border: 1px solid var(--color-border);
  border-radius: 4px;
}

/* 暗色主题 */
html.dark {
  --w-e-textarea-bg-color: #333;
  --w-e-textarea-color: #fff;
  /* ...other... */
}

.dynamic-section {
  margin-top: 16px;
}

.dynamic-list {
  min-height: 100px;
}

.dynamic-item {
  padding: 12px 0;
  border-bottom: 1px solid var(--color-border);
}

.dynamic-item:last-child {
  border-bottom: none;
}

.dynamic-content {
  font-size: 14px;
  color: var(--color-text-1);
  line-height: 1.6;
}

.dynamic-time {
  font-size: 12px;
  color: var(--color-text-3);
  margin-top: 4px;
}

.load-more {
  display: flex;
  justify-content: center;
  padding: 16px 0 0;
}

.member-edit-content {
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.member-info {
  display: flex;
  align-items: center;
  gap: 12px;
}

.member-name {
  font-size: 14px;
  color: var(--color-text-1);
  font-weight: 500;
}

.edit-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.section-label {
  font-size: 14px;
  color: var(--color-text-2);
  margin-bottom: 4px;
}

.role-select {
  margin-top: 8px;
}

/* 编辑按钮样式 */
.member-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
}

.member-item:hover {
  background-color: var(--color-fill-2);
}

.activity-message {
  flex: 1;
  font-size: 14px; /* 增大字体大小 */
  color: var(--color-text-1); /* 加深文字颜色 */
  line-height: 1.5; /* 增加行高 */
  margin-right: 16px;
  word-break: break-word;
  font-weight: 500; /* 添加字重 */
  letter-spacing: 0.2px; /* 添加字间距 */
}

.activity-user {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 100px;
  flex-shrink: 0;
}

.user-name {
  font-size: 13px; /* 稍微减小用户名字体，让内容更突出 */
  color: var(--color-text-2);
  font-weight: normal;
}

.activity-time {
  font-size: 12px;
  color: var(--color-text-3);
  white-space: nowrap;
  flex-shrink: 0;
  width: 90px;
  text-align: right;
}

/* 添加编辑器全屏样式 */
:deep(.w-e-full-screen-container) {
  z-index: 3000 !important; /* 提高全屏时的层级 */
}

:deep(.w-e-full-screen-container .w-e-text-container) {
  max-height: calc(100vh - 100px) !important; /* 减去工具栏高度 */
}

:deep(.w-e-full-screen-container .toolbar) {
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  right: 0 !important;
  z-index: 3001 !important; /* 工具栏层级比编辑器高 */
}

/* 编辑器容器样式 */
.editor-container {
  position: relative;
  width: 100%;
}

/* 工具栏样式 */
:deep(.toolbar) {
  background-color: var(--color-bg-2);
  border: 1px solid var(--color-border);
  border-bottom: none;
  border-radius: 4px 4px 0 0;
}

/* 编辑器内容区域样式 */
:deep(.w-e-text-container) {
  border: 1px solid var(--color-border) !important;
  border-radius: 0 0 4px 4px !important;
}

/* 全屏模式下的工具栏和编辑器样式 */
:deep(.w-e-full-screen-container .toolbar),
:deep(.w-e-full-screen-container .w-e-text-container) {
  width: 100% !important;
  max-width: 100% !important;
  border: none !important;
}

/* 修改全屏模式下的样式 */
:deep(.w-e-full-screen-container) {
  z-index: 3000 !important;
  padding-top: 40px !important; /* 为工具栏预留空间 */
}

:deep(.w-e-full-screen-container .w-e-text-container) {
  max-height: calc(100vh - 40px) !important; /* 减去工具栏高度 */
  height: calc(100vh - 40px) !important;
  padding-top: 8px !important; /* 添加内容顶部间距 */
}

:deep(.w-e-full-screen-container .toolbar) {
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  right: 0 !important;
  z-index: 3001 !important;
  height: 40px !important; /* 固定工具栏高度 */
  display: flex !important;
  align-items: center !important;
  background-color: var(--color-bg-2) !important;
  border-bottom: 1px solid var(--color-border) !important;
}

/* 编辑器内容区域样式 */
:deep(.w-e-text-container .w-e-text) {
  padding: 16px !important; /* 增加内容区域的内边距 */
}

/* 全屏模式下的内容区域样式 */
:deep(.w-e-full-screen-container .w-e-text) {
  padding: 20px !important; /* 全屏模式下增加内边距 */
}

/* 添加字符计数样式 */
.char-count {
  text-align: right;
  padding: 4px 8px;
  color: var(--color-text-3);
  font-size: 12px;
}

/* 当接近字符限制时显示警告色 */
.char-count.warning {
  color: var(--color-warning-6);
}

/* 当超出字符限制时显示错误色 */
.char-count.error {
  color: var(--color-danger-6);
}

/* 修改编辑器内容区域的行高 */
:deep(.w-e-text-container .w-e-text) {
  padding: 16px !important;
  line-height: 1 !important; /* 设置默认行高为 1 */
}

:deep(.w-e-text-container .w-e-text p) {
  margin: 0 !important;
  line-height: 1 !important;
}

/* 全屏模式下的内容区域样式 */
:deep(.w-e-full-screen-container .w-e-text) {
  padding: 20px !important;
  line-height: 1 !important;
}

:deep(.w-e-full-screen-container .w-e-text p) {
  margin: 0 !important;
  line-height: 1 !important;
}

/* 确保所有编辑器内容都使用相同的行高 */
:deep(.w-e-text-container *) {
  line-height: 1 !important;
}

/* 添加状态显示样式 */
.status-display {
  padding: 4px 8px;
  background-color: var(--color-fill-2);
  border-radius: 4px;
  border: 1px solid var(--color-border);
}

.status-option {
  display: flex;
  align-items: center;
  gap: 8px;
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

/* 项目信息卡片基础样式 */
.project-info-card {
  position: relative;
  overflow: hidden;
}

/* 添加渐变遮罩 */
.project-info-card::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 100%;
  background: linear-gradient(to bottom, transparent 30%, var(--gradient-color));
  opacity: 0.1;
  pointer-events: none;
}

/* 规划中状态 */
.project-info-card.status-0::after {
  --gradient-color: rgb(var(--gray-6));
}

/* 进行中状态 */
.project-info-card.status-1::after {
  --gradient-color: rgb(var(--primary-6));
}

/* 暂停中状态 */
.project-info-card.status-2::after {
  --gradient-color: rgb(var(--warning-6));
}

/* 已逾期状态 */
.project-info-card.status-3::after {
  --gradient-color: rgb(var(--danger-6));
}

/* 已完成状态 */
.project-info-card.status-4::after {
  --gradient-color: rgb(var(--success-6));
}

/* 已废弃状态 */
.project-info-card.status-5::after {
  --gradient-color: rgb(var(--gray-8));
}

/* 项目信息卡片基础样式 */
.info-card {
  position: relative;
  overflow: hidden;
}

/* 添加渐变遮罩 */
.info-card::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 100%;
  background: linear-gradient(to bottom, transparent 30%, var(--gradient-color));
  opacity: 0.1;
  pointer-events: none;
  z-index: 1;
}

/* 规划中状态 */
.status-0::after {
  --gradient-color: rgb(var(--gray-6));
}

/* 进行中状态 */
.status-1::after {
  --gradient-color: rgb(var(--primary-6));
}

/* 暂停中状态 */
.status-2::after {
  --gradient-color: rgb(var(--warning-6));
}

/* 已逾期状态 */
.status-3::after {
  --gradient-color: rgb(var(--danger-6));
}

/* 已完成状态 */
.status-4::after {
  --gradient-color: rgb(var(--success-6));
}

/* 已废弃状态 */
.status-5::after {
  --gradient-color: rgb(var(--gray-8));
}

/* 确保卡片内容在渐变层之上 */
.info-card :deep(.arco-card-body) {
  position: relative;
  z-index: 2;
}

.attachment-section {
  margin-top: 24px;
}

.attachment-section h3 {
  font-size: 16px;
  font-weight: 500;
  margin-bottom: 16px;
  color: var(--color-text-1);
}

.upload-area {
  padding: 16px;
  background-color: var(--color-fill-2);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.file-list {
  margin-top: 16px;
}

.file-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px;
  border-radius: 4px;
  transition: background-color 0.2s;
}

.file-item:hover {
  background-color: var(--color-fill-3);
}

.file-info {
  display: flex;
  align-items: center;
  gap: 8px;
}

.file-icon {
  font-size: 24px; /* 统一图标大小 */
  width: 24px; /* 添加固定宽度 */
  height: 24px; /* 添加固定高度 */
  display: flex; /* 使用 flex 布局确保图标居中 */
  align-items: center;
  justify-content: center;
  color: var(--color-text-3);
}

.file-name {
  color: var(--color-text-1);
}

.file-actions {
  opacity: 0;
  transition: opacity 0.2s;
}

.file-item:hover .file-actions {
  opacity: 1;
}

.empty-files {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  color: var(--color-text-3);
  margin-top: 24px;
}

.empty-icon {
  font-size: 48px;
}

/* 为不同类型的文件图标添加不同的颜色，但保持大小一致 */
:deep(.icon-image),
:deep(.icon-music),
:deep(.icon-video),
:deep(.icon-file),
:deep(.icon-pdf),
:deep(.icon-code) {
  font-size: 24px;
  width: 24px;
  height: 24px;
}

:deep(.icon-image) {
  color: rgb(var(--success-6));
}

:deep(.icon-music) {
  color: rgb(var(--warning-6));
}

:deep(.icon-video) {
  color: rgb(var(--danger-6));
}

:deep(.icon-file) {
  color: rgb(var(--primary-6));
}

:deep(.icon-pdf) {
  color: rgb(var(--danger-6));
}

:deep(.icon-code) {
  color: rgb(var(--primary-6));
}

.upload-area {
  padding: 16px;
  background-color: var(--color-fill-2);
  border-radius: 4px;
}

/* 添加上传区域包装器样式 */
.upload-wrapper {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}

.preview-container {
  width: 100%;
  height: calc(100vh - 120px);
  overflow: auto;
}

.preview-container iframe {
  width: 100%;
  height: 100%;
  border: none;
}

.preview-container img {
  max-width: 100%;
  height: auto;
  display: block;
  margin: 0 auto;
}

/* 迭代容器样式 */
.iterations-container {
  padding-left: 12px;
  /* border-left: 1px dashed var(--color-border); */
}

.iteration-item {
  margin-bottom: 16px;
  padding: 12px;
  background-color: var(--color-fill-2);
  border-radius: 4px;
}

.iteration-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  background-color: rgba(0, 180, 42, 0.15);
  border-left: 3px solid rgb(0, 180, 42);
}

.iteration-title-wrapper {
  display: flex;
  align-items: center;
  gap: 8px;
}

.iteration-title {
  font-size: 14px;
  font-weight: 500;
  color: var(--color-text-1);
}

.task-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 8px;
  border-radius: 4px;
  transition: background-color 0.2s;
}

.task-item:hover {
  background-color: var(--color-fill-3);
}

.task-info {
  display: flex;
  align-items: center;
  gap: 8px;
}

.task-date {
  font-size: 12px;
  color: var(--color-text-3);
}

/* 里程碑标题样式优化 */
.milestone-title-wrapper {
  display: flex;
  align-items: center;
  gap: 12px;
}

.milestone-actions {
  display: flex;
  gap: 8px;
}

/* 里程碑弹窗样式 */
.milestone-modal .milestone-form {
  width: 100%;
}

:deep(.w-e-text-container) {
  height: 100% !important;
}

:deep(.w-e-text-container .w-e-scroll) {
  min-height: 150px !important; /* 减小最小高度 */
  height: calc(100% - 20px) !important;
  padding: 10px !important;
}

:deep(.w-e-full-screen-container .w-e-text-container) {
  height: calc(100vh - 40px) !important;
}

:deep(.w-e-full-screen-container .w-e-scroll) {
  height: calc(100vh - 60px) !important;
  min-height: 300px !important;
}

.milestone-detail-modal .milestone-detail-content {
  padding: 16px;
}

.detail-section {
  margin-bottom: 24px;
}

.detail-section h3 {
  font-size: 16px;
  font-weight: 500;
  margin-bottom: 16px;
  color: var(--color-text-1);
}

.info-item {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
}

.info-item .label {
  width: 80px;
  color: var(--color-text-3);
}

.status {
  padding: 2px 8px;
}

.status.completed {
  background-color: rgb(var(--success-6));
  color: #fff;
}

.status.in_progress {
  background-color: rgb(var(--primary-6));
  color: #fff;
}

.status.pending {
  background-color: rgb(var(--warning-6));
  color: #fff;
}

.status.overdue {
  background-color: rgb(var(--danger-6));
  color: #fff;
}

/* 里程碑标题交互样式 */
.milestone-title.clickable {
  cursor: pointer;
  transition: color 0.2s;
}

.milestone-title.clickable:hover {
  color: rgb(var(--primary-6));
}

/* 里程碑详情弹窗样式 */
.milestone-detail-content {
  padding: 16px;
}

.detail-section {
  margin-bottom: 24px;
}

.detail-section h3 {
  font-size: 16px;
  font-weight: 500;
  margin-bottom: 16px;
  color: var(--color-text-1);
}

.info-item {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
}

.info-item .label {
  width: 80px;
  color: var(--color-text-3);
}
</style>
